﻿Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Drawing
Imports System.Workflow.ComponentModel

Namespace System.Workflow.ComponentModel.Design
    Public Class ParallelActivityDesigner
        Inherits StructuredCompositeActivityDesigner
        ' Methods
        Public Overrides Function CanMoveActivities(ByVal moveLocation As HitTestInfo, ByVal activitiesToMove As ReadOnlyCollection([Of] Activity)) As Boolean
            If (moveLocation Is Nothing) Then
                Throw New ArgumentNullException("moveLocation")
            End If
            If (activitiesToMove Is Nothing) Then
                Throw New ArgumentNullException("activitiesToMove")
            End If
            If ((MyBase.ActiveDesigner Is Me) AndAlso ((((Me.ContainedDesigners.Count - activitiesToMove.Count) < 2) AndAlso (Not moveLocation Is Nothing)) AndAlso (Not moveLocation.AssociatedDesigner Is Me))) Then
                Return False
            End If
            Return MyBase.CanMoveActivities(moveLocation, activitiesToMove)
        End Function

        Public Overrides Function CanRemoveActivities(ByVal activitiesToRemove As ReadOnlyCollection([Of] Activity)) As Boolean
            If (activitiesToRemove Is Nothing) Then
                Throw New ArgumentNullException("activitiesToRemove")
            End If
            If ((MyBase.ActiveDesigner Is Me) AndAlso ((Me.ContainedDesigners.Count - activitiesToRemove.Count) < 2)) Then
                Return False
            End If
            Return MyBase.CanRemoveActivities(activitiesToRemove)
        End Function

        Private Sub DrawParallelConnectors(ByVal e As ActivityDesignerPaintEventArgs)
            Dim designerTheme As CompositeDesignerTheme = [TryCast](e.DesignerTheme,CompositeDesignerTheme)
            If (Not designerTheme Is Nothing) Then
                Dim bounds As Rectangle = MyBase.Bounds
                Dim num As Integer = (bounds.Top + Me.TitleHeight)
                Dim containedDesigners As ReadOnlyCollection([Of] ActivityDesigner) = Me.ContainedDesigners
                Dim connections As ReadOnlyCollection([Of] Point) = containedDesigners.Item(0).GetConnections((DesignerEdges.Bottom Or DesignerEdges.Top))
                Dim onlys3 As ReadOnlyCollection([Of] Point) = containedDesigners.Item((containedDesigners.Count - 1)).GetConnections((DesignerEdges.Bottom Or DesignerEdges.Top))
                Dim points As Point() = New Point(2  - 1) {}
                points(0).X = (bounds.Left + (bounds.Width / 2))
                points(0).Y = num
                points(1).X = (bounds.Left + (bounds.Width / 2))
                points(1).Y = (num + ((designerTheme.ConnectorSize.Height * 3) / 4))
                MyBase.DrawConnectors(e.Graphics, designerTheme.ForegroundPen, points, LineAnchor.None, LineAnchor.None)
                Dim point As Point = connections.Item(0)
                points(0).X = point.X
                points(0).Y = (num + ((designerTheme.ConnectorSize.Height * 3) / 4))
                Dim point2 As Point = onlys3.Item(0)
                points(1).X = point2.X
                points(1).Y = (num + ((designerTheme.ConnectorSize.Height * 3) / 4))
                MyBase.DrawConnectors(e.Graphics, designerTheme.ForegroundPen, points, LineAnchor.None, LineAnchor.None)
                Dim point3 As Point = connections.Item((connections.Count - 1))
                points(0).X = point3.X
                points(0).Y = (bounds.Bottom - ((designerTheme.ConnectorSize.Height * 3) / 4))
                Dim point4 As Point = onlys3.Item((onlys3.Count - 1))
                points(1).X = point4.X
                points(1).Y = (bounds.Bottom - ((designerTheme.ConnectorSize.Height * 3) / 4))
                MyBase.DrawConnectors(e.Graphics, designerTheme.ForegroundPen, points, LineAnchor.None, LineAnchor.None)
                points(0).X = (bounds.Left + (bounds.Width / 2))
                points(0).Y = (bounds.Bottom - ((designerTheme.ConnectorSize.Height * 3) / 4))
                points(1).X = (bounds.Left + (bounds.Width / 2))
                points(1).Y = bounds.Bottom
                MyBase.DrawConnectors(e.Graphics, designerTheme.ForegroundPen, points, LineAnchor.None, LineAnchor.None)
                Dim designer3 As ActivityDesigner
                For Each designer3 In containedDesigners
                    Dim onlys4 As ReadOnlyCollection([Of] Point) = designer3.GetConnections((DesignerEdges.Bottom Or DesignerEdges.Top))
                    Dim count As Integer = onlys4.Count
                    Dim pointArray2 As Point() = New Point(2  - 1) {}
                    Dim point5 As Point = onlys4.Item(0)
                    pointArray2(0).X = point5.X
                    pointArray2(0).Y = (num + ((designerTheme.ConnectorSize.Height * 3) / 4))
                    Dim point6 As Point = onlys4.Item(0)
                    pointArray2(1).X = point6.X
                    Dim point7 As Point = onlys4.Item(0)
                    pointArray2(1).Y = point7.Y
                    MyBase.DrawConnectors(e.Graphics, designerTheme.ForegroundPen, pointArray2, designerTheme.ConnectorStartCap, designerTheme.ConnectorEndCap)
                    Dim point8 As Point = onlys4.Item((count - 1))
                    pointArray2(0).X = point8.X
                    Dim point9 As Point = onlys4.Item((count - 1))
                    pointArray2(0).Y = point9.Y
                    Dim point10 As Point = onlys4.Item((count - 1))
                    pointArray2(1).X = point10.X
                    pointArray2(1).Y = (bounds.Bottom - ((designerTheme.ConnectorSize.Height * 3) / 4))
                    MyBase.DrawConnectors(e.Graphics, designerTheme.ForegroundPen, pointArray2, designerTheme.ConnectorStartCap, designerTheme.ConnectorEndCap)
                Next
            End If
        End Sub

        Private Sub DrawParallelDropTargets(ByVal e As ActivityDesignerPaintEventArgs, ByVal index As Integer)
            Dim dropTargets As Rectangle() = Me.GetDropTargets(Point.Empty)
            If ((index >= 0) AndAlso (index < dropTargets.Length)) Then
                Dim designerTheme As CompositeDesignerTheme = [TryCast](e.DesignerTheme,CompositeDesignerTheme)
                If (Not designerTheme Is Nothing) Then
                    Dim containedDesigners As ReadOnlyCollection([Of] ActivityDesigner) = Me.ContainedDesigners
                    Dim rectangle As Rectangle = dropTargets(index)
                    Dim bounds As Rectangle = MyBase.Bounds
                    Dim num As Integer = (bounds.Top + Me.TitleHeight)
                    num = (num + If((containedDesigners.Count > 0), ((designerTheme.ConnectorSize.Height * 3) / 4), 0))
                    Dim num2 As Integer = (rectangle.Y - num)
                    num2 = (num2 + (bounds.Bottom - rectangle.Bottom))
                    num2 = (num2 - If((containedDesigners.Count > 0), ((designerTheme.ConnectorSize.Height * 3) / 4), 0))
                    rectangle.Y = num
                    rectangle.Height = (rectangle.Height + num2)
                    Dim points As Point() = New Point() { New Point((rectangle.Left + (rectangle.Width / 2)), (rectangle.Top + 2)), New Point((rectangle.Left + (rectangle.Width / 2)), (rectangle.Bottom - 2)) }
                    MyBase.DrawConnectors(e.Graphics, e.AmbientTheme.DropIndicatorPen, points, designerTheme.ConnectorStartCap, designerTheme.ConnectorEndCap)
                    If (containedDesigners.Count > 0) Then
                        If (index = 0) Then
                            Dim connections As ReadOnlyCollection([Of] Point) = containedDesigners.Item(0).GetConnections((DesignerEdges.Bottom Or DesignerEdges.Top))
                            Dim pointArray As Point() = New Point(2  - 1) {}
                            pointArray(0).X = (rectangle.X + (rectangle.Width / 2))
                            pointArray(0).Y = rectangle.Y
                            Dim point As Point = connections.Item(0)
                            pointArray(1).X = point.X
                            pointArray(1).Y = rectangle.Y
                            MyBase.DrawConnectors(e.Graphics, e.AmbientTheme.DropIndicatorPen, pointArray, LineAnchor.None, LineAnchor.None)
                            pointArray(0).Y = rectangle.Bottom
                            pointArray(1).Y = rectangle.Bottom
                            MyBase.DrawConnectors(e.Graphics, e.AmbientTheme.DropIndicatorPen, pointArray, LineAnchor.None, LineAnchor.None)
                        ElseIf (index = containedDesigners.Count) Then
                            Dim onlys3 As ReadOnlyCollection([Of] Point) = containedDesigners.Item((containedDesigners.Count - 1)).GetConnections((DesignerEdges.Bottom Or DesignerEdges.Top))
                            Dim pointArray2 As Point() = New Point(2  - 1) {}
                            Dim point2 As Point = onlys3.Item(0)
                            pointArray2(0).X = point2.X
                            pointArray2(0).Y = rectangle.Y
                            pointArray2(1).X = (rectangle.X + (rectangle.Width / 2))
                            pointArray2(1).Y = rectangle.Y
                            MyBase.DrawConnectors(e.Graphics, e.AmbientTheme.DropIndicatorPen, pointArray2, LineAnchor.None, LineAnchor.None)
                            pointArray2(0).Y = rectangle.Bottom
                            pointArray2(1).Y = rectangle.Bottom
                            MyBase.DrawConnectors(e.Graphics, e.AmbientTheme.DropIndicatorPen, pointArray2, LineAnchor.None, LineAnchor.None)
                        End If
                    End If
                End If
            End If
        End Sub

        Protected Overrides Function GetDropTargets(ByVal dropPoint As Point) As Rectangle()
            If (Not Me.Expanded OrElse (Not MyBase.ActiveDesigner Is Me)) Then
                Return New Rectangle(0  - 1) {}
            End If
            Dim designerTheme As CompositeDesignerTheme = [TryCast](MyBase.DesignerTheme,CompositeDesignerTheme)
            Dim bounds As Rectangle = MyBase.Bounds
            Dim containedDesigners As ReadOnlyCollection([Of] ActivityDesigner) = Me.ContainedDesigners
            Dim rectangleArray As Rectangle() = New Rectangle((containedDesigners.Count + 1)  - 1) {}
            If (containedDesigners.Count > 0) Then
                Dim designer As ActivityDesigner = containedDesigners.Item(0)
                rectangleArray(0).Location = New Point(bounds.X, designer.Location.Y)
                rectangleArray(0).Size = New Size(If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Width, 0), designer.Size.Height)
                Dim i As Integer
                For i = 0 To (containedDesigners.Count - 1) - 1
                    Dim designer2 As ActivityDesigner = containedDesigners.Item(i)
                    Dim rectangle2 As Rectangle = designer2.Bounds
                    Dim designer3 As ActivityDesigner = containedDesigners.Item((i + 1))
                    Dim rectangle3 As Rectangle = designer3.Bounds
                    rectangleArray((i + 1)).Location = New Point(((rectangle2.Right + ((rectangle3.Left - rectangle2.Right) / 2)) - (If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Width, 0) / 2)), rectangle2.Top)
                    rectangleArray((i + 1)).Size = New Size(If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Width, 0), rectangle2.Height)
                Next i
                Dim designer4 As ActivityDesigner = containedDesigners.Item((containedDesigners.Count - 1))
                rectangleArray(containedDesigners.Count).Location = New Point((bounds.Right - If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Width, 0)), designer4.Location.Y)
                rectangleArray(containedDesigners.Count).Size = New Size(If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Width, 0), designer4.Size.Height)
                Return rectangleArray
            End If
            rectangleArray(0).Location = New Point((Me.Location.X + ((Me.Size.Width - If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Width, 0)) / 2)), Me.TextRectangle.Bottom)
            rectangleArray(0).Size = New Size(If((Not designerTheme Is Nothing), designerTheme.ConnectorSize.Width, 0), ((Me.Location.Y + Me.Size.Height) - rectangleArray(0).Location.Y))
            Return rectangleArray
        End Function

        Public Overrides Function GetNextSelectableObject(ByVal obj As Object, ByVal direction As DesignerNavigationDirection) As Object
            If (Not MyBase.ActiveDesigner Is Me) Then
                Return MyBase.GetNextSelectableObject(obj, direction)
            End If
            If ((direction <> DesignerNavigationDirection.Left) AndAlso (direction <> DesignerNavigationDirection.Right)) Then
                Return Nothing
            End If
            Dim activity As Object = Nothing
            Dim containedDesigners As ReadOnlyCollection([Of] ActivityDesigner) = Me.ContainedDesigners
            Dim designer As ActivityDesigner = ActivityDesigner.GetDesigner([TryCast](obj,Activity))
            Dim num As Integer = If((Not designer Is Nothing), containedDesigners.IndexOf(designer), -1)
            If (((direction = DesignerNavigationDirection.Left) AndAlso (num >= 0)) AndAlso (num < containedDesigners.Count)) Then
                Return containedDesigners.Item(If((num > 0), (num - 1), (containedDesigners.Count - 1))).Activity
            End If
            If ((direction = DesignerNavigationDirection.Right) AndAlso (num <= (containedDesigners.Count - 1))) Then
                activity = containedDesigners.Item(If((num < (containedDesigners.Count - 1)), (num + 1), 0)).Activity
            End If
            Return activity
        End Function

        Private Sub OnAddBranch(ByVal sender As Object, ByVal e As EventArgs)
            Dim activity As CompositeActivity = Me.OnCreateNewBranch
            Dim activity2 As CompositeActivity = [TryCast](MyBase.Activity,CompositeActivity)
            If ((Not activity2 Is Nothing) AndAlso (Not activity Is Nothing)) Then
                Dim count As Integer = Me.ContainedDesigners.Count
                CompositeActivityDesigner.InsertActivities(Me, New ConnectorHitTestInfo(Me, HitTestLocations.Designer, activity2.Activities.Count), New List([Of] Activity)(New Activity() { activity }).AsReadOnly, DR.GetString("AddingBranch", New Object() { activity.GetType.Name }))
                If ((Me.ContainedDesigners.Count > count) AndAlso (Me.ContainedDesigners.Count > 0)) Then
                    Me.ContainedDesigners.Item((Me.ContainedDesigners.Count - 1)).EnsureVisible
                End If
            End If
        End Sub

        Protected Overridable Function OnCreateNewBranch() As CompositeActivity
            Return Nothing
        End Function

        Protected Overrides Sub OnLayoutPosition(ByVal e As ActivityDesignerLayoutEventArgs)
            If (e Is Nothing) Then
                Throw New ArgumentNullException("e")
            End If
            MyBase.OnLayoutPosition(e)
            If (Me.Expanded AndAlso (MyBase.ActiveDesigner Is Me)) Then
                Dim designerTheme As CompositeDesignerTheme = [TryCast](e.DesignerTheme,CompositeDesignerTheme)
                If (Not designerTheme Is Nothing) Then
                    Dim innerConnections As ReadOnlyCollection([Of] Point) = Me.GetInnerConnections((DesignerEdges.Bottom Or DesignerEdges.Top))
                    Dim point As Point = If((innerConnections.Count > 0), New Point(Me.Location.X, innerConnections.Item(0).Y), Me.Location)
                    Dim num As Integer = 0
                    Dim num2 As Integer = ((designerTheme.ConnectorSize.Height * 3) / 2)
                    Dim designer As ActivityDesigner
                    For Each designer In Me.ContainedDesigners
                        num = (num + e.AmbientTheme.SelectionSize.Width)
                        num = (num + designerTheme.ConnectorSize.Width)
                        Dim size As Size = designer.Size
                        designer.Location = New Point((point.X + num), (point.Y + num2))
                        num = (num + size.Width)
                        num = (num + e.AmbientTheme.SelectionSize.Width)
                    Next
                End If
            End If
        End Sub

        Protected Overrides Function OnLayoutSize(ByVal e As ActivityDesignerLayoutEventArgs) As Size
            Dim size As Size = MyBase.OnLayoutSize(e)
            Dim designerTheme As CompositeDesignerTheme = [TryCast](e.DesignerTheme,CompositeDesignerTheme)
            If ((Me.Expanded AndAlso (MyBase.ActiveDesigner Is Me)) AndAlso (Not designerTheme Is Nothing)) Then
                Dim empty As Size = Size.Empty
                Dim designer As ActivityDesigner
                For Each designer In Me.ContainedDesigners
                    Dim size3 As Size = designer.Size
                    empty.Width = (empty.Width + e.AmbientTheme.SelectionSize.Width)
                    empty.Width = (empty.Width + designerTheme.ConnectorSize.Width)
                    empty.Width = (empty.Width + size3.Width)
                    empty.Width = (empty.Width + e.AmbientTheme.SelectionSize.Width)
                    empty.Height = Math.Max(empty.Height, size3.Height)
                Next
                empty.Width = (empty.Width + If((Me.ContainedDesigners.Count > 0), designerTheme.ConnectorSize.Width, 0))
                Dim designer2 As ActivityDesigner
                For Each designer2 In Me.ContainedDesigners
                    designer2.Size = New Size(designer2.Size.Width, empty.Height)
                Next
                empty.Height = (empty.Height + (3 * designerTheme.ConnectorSize.Height))
                size.Width = Math.Max(size.Width, empty.Width)
                size.Height = (size.Height + empty.Height)
            End If
            Return size
        End Function

        Protected Overrides Sub OnPaint(ByVal e As ActivityDesignerPaintEventArgs)
            MyBase.OnPaint(e)
            If (Me.Expanded AndAlso (MyBase.ActiveDesigner Is Me)) Then
                If (Me.ContainedDesigners.Count > 0) Then
                    Me.DrawParallelConnectors(e)
                End If
                If (Me.CurrentDropTarget >= 0) Then
                    Me.DrawParallelDropTargets(e, Me.CurrentDropTarget)
                End If
            End If
        End Sub

        Private Sub OnStatusAddBranch(ByVal sender As Object, ByVal e As EventArgs)
            Dim verb As ActivityDesignerVerb = [TryCast](sender,ActivityDesignerVerb)
            If (Not verb Is Nothing) Then
                verb.Enabled = MyBase.IsEditable
            End If
        End Sub


        ' Properties
        Public Overrides ReadOnly Property FirstSelectableObject As Object
            Get
                If (Not MyBase.ActiveDesigner Is Me) Then
                    Return MyBase.FirstSelectableObject
                End If
                If (Not Me.Expanded OrElse Not Me.IsVisible) Then
                    Return Nothing
                End If
                Dim activity As Object = Nothing
                If (Me.ContainedDesigners.Count > 0) Then
                    activity = Me.ContainedDesigners.Item(0).Activity
                End If
                Return activity
            End Get
        End Property

        Public Overrides ReadOnly Property LastSelectableObject As Object
            Get
                If (Not MyBase.ActiveDesigner Is Me) Then
                    Return MyBase.FirstSelectableObject
                End If
                If (Not Me.Expanded OrElse Not Me.IsVisible) Then
                    Return Nothing
                End If
                Dim obj2 As Object = If((Me.ContainedDesigners.Count > 0), Me.ContainedDesigners.Item(0).Activity, Nothing)
                Dim designer As CompositeActivityDesigner = If(TypeOf obj2 Is Activity, [TryCast](ActivityDesigner.GetDesigner([TryCast](obj2,Activity)),CompositeActivityDesigner), Nothing)
                Dim lastSelectableObject As Object = Nothing
                If (Not designer Is Nothing) Then
                    lastSelectableObject = designer.LastSelectableObject
                End If
                If (lastSelectableObject Is Nothing) Then
                    lastSelectableObject = obj2
                End If
                Return lastSelectableObject
            End Get
        End Property

        Protected Overrides ReadOnly Property Verbs As ActivityDesignerVerbCollection
            Get
                Dim verbs As New ActivityDesignerVerbCollection
                verbs.AddRange(MyBase.Verbs)
                If (Me.designerVerbs Is Nothing) Then
                    Me.designerVerbs = New ActivityDesignerVerbCollection
                    Me.designerVerbs.Add(New ActivityDesignerVerb(Me, DesignerVerbGroup.General, DR.GetString("AddBranch", New Object(0  - 1) {}), New EventHandler(AddressOf Me.OnAddBranch), New EventHandler(AddressOf Me.OnStatusAddBranch)))
                End If
                verbs.AddRange(Me.designerVerbs)
                Return verbs
            End Get
        End Property


        ' Fields
        Private designerVerbs As ActivityDesignerVerbCollection
    End Class
End Namespace

